package ltd.nullpointer.tcp.core;

import com.boot2.core.utils.ByteUtils;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.apachecommons.CommonsLog;
import ltd.nullpointer.tcp.core.constant.AesKeyHolder;
import ltd.nullpointer.tcp.core.constant.TCPEnum;
import ltd.nullpointer.tcp.core.exception.MessageResolverException;
import ltd.nullpointer.tcp.core.resolver.MessageResolverFactory;
import ltd.nullpointer.tcp.core.util.AesUtil;

import java.util.List;

/**
 * 
 * @ClassName: DeviceMessageDecoder
 * @Description: 解码器.
 * @author zhangweilin
 * @date 2017年11月9日 下午1:25:12
 *
 */

@CommonsLog
public class DeciphMessageDecoder extends ByteToMessageDecoder {

	@Override
	protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
//		ByteBuf copy = in.retainedDuplicate();
		int len = in.readableBytes();
		byte[] bytes = new byte[len];
		in.readBytes(bytes);
		in.resetReaderIndex();
		String hexString = ByteUtils.hexBytes2HexString(bytes);

		log.debug("收到原始报文，转换成16进制原始字符串后，hexString = " + hexString);

		// 是否需要走加密逻辑
		boolean isNeedEncrypt = false;
		try {
			isNeedEncrypt = MessageResolverFactory.getInstance().getResolver(in).isNeedEncrypt();
		} catch (Exception e) {
			e.printStackTrace();
			throw new MessageResolverException(TCPEnum.ErrorCode.err10002.getErrCode(), TCPEnum.ErrorCode.err10002.getName(),e,"连接信息: "+ctx);
		}
		String aesKey = getAesKey(ctx);
		if (!isNeedEncrypt) {
//			out.add(in.retainedDuplicate());
			out.add(in);
			// ReferenceCountUtil.retain(in);//这行
//			in.skipBytes(in.readableBytes());
			return;
		}


//		System.out.println("解密前: " + Arrays.toString(bytes));

		System.out.println("DeciphMessageDecoder.aesKey: " + aesKey);
		byte[] bytes2 = AesUtil.aesDecode(aesKey, bytes);
		bytes = null;
		ByteBuf outByteBuf = Unpooled.buffer(bytes2.length);
		outByteBuf.writeBytes(bytes2);
		// outByteBuf=outByteBuf.retainedDuplicate();
		out.add(outByteBuf);
//		in.skipBytes(in.readableBytes());
//		System.out.println("解密后: " + Arrays.toString(bytes2));
		bytes2 = null;
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
		log.error("Decoder error: " + cause.getMessage(), cause);
		cause.printStackTrace();
		ctx.close();
	}

	protected String getAesKey(ChannelHandlerContext ctx) {
		return AesKeyHolder.getAesKey();
	}

}
